package com.dc.commons.config.repository;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Named;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import com.dc.commons.config.profile.DevelopConfig;
import com.dc.commons.config.profile.FunctionalConfig;
import com.dc.commons.config.profile.ProdunctionConfig;
import com.dc.commons.config.profile.TestingConfig;
import com.dc.commons.jpa.repository.factory.DcRepositoryFactoryBean;
import com.dc.commons.utils.Hibernates;
/*******************************************************************************<P>
 * 文件名: RepositoryConfig.java <br>
 * 版本: 1.0<br>
 * 描述: 数据访问层配置 包括 JPA <br>
 * 版权所有: <br>
 * <P>
 * 创建者: 王建栋 <br>
 * 创建日期: 2015年12月17日 上午9:53:44<br>
 * 修改者: <br>
 * 修改日期: <br>
 * 修改说明: <br>
 *****************************************************************************
 */
@Configuration
@EnableJpaRepositories(
		basePackages={"com.dc.modules.**.repository"},
		entityManagerFactoryRef="entityManagerFactory",
		transactionManagerRef="transactionManager",
		repositoryFactoryBeanClass=DcRepositoryFactoryBean.class)
@Import({ProdunctionConfig.class,DevelopConfig.class,TestingConfig.class,FunctionalConfig.class})
public class RepositoryConfig {


	
	@Autowired
	@Named("dataSource")
	private DataSource dataSource;
	
	
	private Map<String,Object> jpaProperties(){
		Map<String,Object> map=new HashMap<String,Object>();
		map.put("hibernate.ejb.naming_strategy", hibernate_ejb_naming_strategy);
		map.put("hibernate.show_sql", hibernate_show_sql);
		map.put("hibernate.hbm2ddl.auto", hibernate_hbm2ddl_auto);
		map.put("hibernate.cache.region.factory_class", hibernate_cache_region_factory_class);
		map.put("net.sf.ehcache.configurationResourceName", net_sf_ehcache_configurationResourceName);
		map.put("hibernate.cache.use_second_level_cache", hibernate_cache_use_second_level_cache);
		map.put("hibernate.cache.use_query_cache", hibernate_cache_use_query_cache);
		map.put("hibernate.max_fetch_depth", hibernate_max_fetch_depth);
		return map;
	}
	
	
	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
		LocalContainerEntityManagerFactoryBean factoryBean=new LocalContainerEntityManagerFactoryBean();
		factoryBean.setDataSource(dataSource);
		factoryBean.setPackagesToScan("com.dc.modules.**.domain");
		factoryBean.setJpaVendorAdapter(hibernateJpaVendorAdapter());
		factoryBean.setJpaPropertyMap(jpaProperties());
		return factoryBean;
	}
	
	@Bean
	public HibernateJpaVendorAdapter hibernateJpaVendorAdapter(){
		HibernateJpaVendorAdapter hibernateJpaVendorAdapter=new HibernateJpaVendorAdapter();
		hibernateJpaVendorAdapter.setDatabasePlatform(Hibernates.getDialect(dataSource));
		return hibernateJpaVendorAdapter;
	}
	
	@Bean
	public JpaTransactionManager transactionManager(){
		JpaTransactionManager transactionManager=new JpaTransactionManager();
		transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
		return transactionManager;
	}
	
	@Bean
	public LocalValidatorFactoryBean validator(){
		LocalValidatorFactoryBean validator=new LocalValidatorFactoryBean();
		return validator;
	}
	
	@Value("${hibernate.ejb.naming_strategy}")
	private String hibernate_ejb_naming_strategy;
	
	@Value("${hibernate.show_sql}")
	private boolean hibernate_show_sql;
	
	@Value("${hibernate.hbm2ddl.auto}")
	private String hibernate_hbm2ddl_auto;
	
	@Value("${hibernate.cache.region.factory_class}")
	private String hibernate_cache_region_factory_class;
	
	@Value("${net.sf.ehcache.configurationResourceName}")
	private String net_sf_ehcache_configurationResourceName;
	
	@Value("${hibernate.cache.use_second_level_cache}")
	private boolean hibernate_cache_use_second_level_cache;
	
	@Value("${hibernate.cache.use_query_cache}")
	private boolean hibernate_cache_use_query_cache;
	
	@Value("${hibernate.max_fetch_depth}")
	private int hibernate_max_fetch_depth;
}
